﻿using FirstFloor.ModernUI.Presentation;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

using System.Windows.Documents;
using System.Windows.Documents.Serialization;
using System.Windows.Markup;
using System.Windows;

using iTextSharp.text;
using iTextSharp.text.pdf;
using System.IO;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using FirstFloor.ModernUI.Windows.Controls;
using System.Diagnostics;

using Microsoft.Practices.Unity;
using appCtx = EasyInvoice.ApplicationContext.AppContext;


namespace EasyInvoice.WPF.ViewModel
{
    class InvoiceListViewModel : NotifyPropertyChanged
    {
        private Services.InvoicesService _serviceInvoices;

        public LinkCollection InvoiceLinks
        {
            get
            {

                return new LinkCollection(from InvoiceViewModel invoice in GetInvoices()
                                          select new Link()
                                          {
                                              DisplayName = invoice.Number + " from " + invoice.Date.ToString("yyyy MM dd"),
                                              Source = new Uri(invoice.Id.ToString(), UriKind.Relative)
                                          }
                          );
            }
        }

        public InvoiceListViewModel()
        {
            this._serviceInvoices = appCtx.Instance.IoC.Resolve<Services.InvoicesService>();
        }

        private ObservableCollection<InvoiceViewModel> GetInvoices()
        {
            var returnValue = new ObservableCollection<InvoiceViewModel>();
            var invoices = this._serviceInvoices.GetAll();

            invoices = from Model.Invoice c in invoices 
                       where c.Date >= _startDate 
                       && c.Date <= _endDate 
                       && c.Number.Contains(_number) 
                       && (_filterClient.Id==0?0:_filterClient.Id) == (_filterClient.Id==0?0:c.ClientId)
                       && (_filterSeller.Id == 0 ? 0 : _filterSeller.Id) == (_filterSeller.Id == 0 ? 0 : c.SellerId)
                       select c;
            invoices.ToList().ForEach(invoice => returnValue.Add(new InvoiceViewModel(invoice)));

            return returnValue;
        }

        #region Filter properties
        
        private DateTime _startDate = DateTime.Today.AddYears(-1);

        public DateTime StartDate
        {
            get
            {
                return this._startDate;
            }
            set
            {
                this._startDate = value;
                this.OnPropertyChanged("StartDate");
            }
        }

        private DateTime _endDate = DateTime.Today;
        
        public DateTime EndDate
        {
            get
            {
                return this._endDate;
            }
            set
            {
                this._endDate = value;
                this.OnPropertyChanged("EndDate");
            }
        }

        private string _number = string.Empty;

        public string Number
        {
            get
            {
                return this._number;
            }
            set
            {
                this._number = value;
                this.OnPropertyChanged("Number");
            }
        }

        private ClientViewModel _filterClient = Repository.GetFilterClients().First(i => i.Id == 0);

        public ClientViewModel FilterClient
        {
            get
            {
                return this._filterClient;
            }
            set
            {
                this._filterClient = value;
                OnPropertyChanged("FilterClient");
            }

        }

        private ClientViewModel _filterSeller = Repository.GetFilterSellers().First(i => i.Id == 0);

        public ClientViewModel FilterSeller
        {
            get
            {
                return this._filterSeller;
            }
            set
            {
                this._filterSeller = value;
                OnPropertyChanged("FilterSeller");
            }

        }

        #endregion

        public Uri SelectedLink { get; set; }

        //for opening up the Add Client window
        private ICommand showAddCommand;

        public ICommand ShowAddCommand
        {
            get
            {
                if (showAddCommand == null)
                {
                    showAddCommand = new Common.CommandBase(
                        i => this.AddInvoice(),
                        i => ((UserViewModel)Properties.Settings.Default.AuthenticatedUser) != null ? ((UserViewModel)Properties.Settings.Default.AuthenticatedUser).AddInvoices : false);
                }
                return showAddCommand;
            }
        }

        private void AddInvoice()
        {
            SelectedLink = new Uri(string.Format("0|{0}", DateTime.Now.Ticks), UriKind.Relative);
            this.OnPropertyChanged("SelectedLink");
        }

        //for opening up the Delete Client window
        private ICommand showDeleteCommand;

        public ICommand ShowDeleteCommand
        {
            get
            {
                if (showDeleteCommand == null)
                {
                    showDeleteCommand = new Common.CommandBase(
                        i => this.DeleteInvoice(),
                        i => this.CanDelete());
                }
                return showDeleteCommand;
            }
        }

        private void DeleteInvoice()
        {
            InvoiceViewModel invoice = new InvoiceViewModel(this._serviceInvoices.Get(Convert.ToInt32(SelectedLink.ToString())));
            var result = ModernDialog.ShowMessage(string.Format("Do you want to delete invoice number {0} from {1}?",invoice.Number, invoice.Date.ToString("MMMM dd, yyyy")), "Delete Invoice Dialog", MessageBoxButton.YesNo);
            if (result == MessageBoxResult.Yes)
            {
                try
                {
                    invoice.Delete();
                    if (InvoiceLinks.Count > 0) SelectedLink = InvoiceLinks.First().Source;
                }
                catch (Exception ex)
                {
                    ModernDialog.ShowMessage(ex.Message, "Delete Invoice Failed", MessageBoxButton.OK);
                }
            }
            this.OnPropertyChanged("InvoiceLinks");
            this.OnPropertyChanged("SelectedLink");
            
        }

        private bool CanDelete()
        {
            if (object.Equals((UserViewModel)Properties.Settings.Default.AuthenticatedUser, null)) return false;
            if (object.Equals(SelectedLink, null)) return false;
            if (SelectedLink.OriginalString.Contains("|")) return false;
            return ((UserViewModel)Properties.Settings.Default.AuthenticatedUser).DeleteInvoices;
        }
        //for opening up the Add Client window
        private ICommand printCommand;

        public ICommand PrintCommand
        {
            get
            {
                if (printCommand == null)
                {
                    printCommand = new Common.CommandBase(
                        i => this.PrintInvoice(),
                        i => CanPrint());
                }
                return printCommand;
            }
        }

        private void PrintInvoice()
        {
            InvoiceViewModel invoice = new InvoiceViewModel(this._serviceInvoices.Get(Convert.ToInt32(SelectedLink.ToString())));
            new Common.InvoiceDocument(invoice, string.Format("{0}\\{1}-{2}.pdf",EasyInvoice.WPF.Properties.Settings.Default.ExportFolderLocation, invoice.Number, invoice.Date.ToString("yyyy-MM-dd")));
            var result = ModernDialog.ShowMessage(
                string.Format("Invoice Number {0} from {1} is saved to file {0}-{2}.pdf. \nDo  you want to open it?", invoice.Number, invoice.Date.ToString("MMMM dd, yyyy"), invoice.Date.ToString("yyyy-MM-dd"))
                , "Invoice Exported to pdf", MessageBoxButton.YesNo);
            if (result == MessageBoxResult.Yes)
                Process.Start(string.Format("{0}\\{1}-{2}.pdf", EasyInvoice.WPF.Properties.Settings.Default.ExportFolderLocation, invoice.Number, invoice.Date.ToString("yyyy-MM-dd")));
        }

        private bool CanPrint()
        {
            if (object.Equals((UserViewModel)Properties.Settings.Default.AuthenticatedUser, null)) return false;
            if (object.Equals(SelectedLink, null)) return false;
            if (SelectedLink.OriginalString.Contains("|")) return false;
            return ((UserViewModel)Properties.Settings.Default.AuthenticatedUser).PrintInvoices;
        }
        #region comments
        //private void PrintInvoice()
        //{
        //    // create an instance of your XAML object (Window or UserControl)
        //    InvoiceViewModel invoice =  new InvoiceViewModel( new Model.Invoice().GetByIdCE( Convert.ToInt32(SelectedLink.ToString())));
        //    EasyInvoice.WPF.Pages.InvoiceReport report = new EasyInvoice.WPF.Pages.InvoiceReport();
        //    report.DataContext = invoice;
            
        //    System.Windows.Window win = new System.Windows.Window();
        //    //win.RenderSize = new Size(96 * 8.5, 96 * 11);
        //    win.Content = report;
        //    win.Show();
        //    //win.Close();
        //    System.Xml.XmlDocument str = (System.Xml.XmlDocument) win.Content;
        //    win.Content = null;
        //    // create a FixedDocument and add a page of your XAML object
        //    var fixedDocument = new FixedDocument();
        //    fixedDocument.DocumentPaginator.PageSize = new Size(96 * 8.5, 96 * 11);

        //    PageContent pageContent = new PageContent();
        //    FixedPage fixedPage = new FixedPage();
            
        //    fixedPage.Children.Add(report);
        //    fixedDocument.Pages.Add(pageContent);
        //    ((IAddChild)pageContent).AddChild(fixedPage);

            

        //    // create an iTextSharp document
        //    Document doc = new Document(PageSize.LETTER, 72, 36, 72, 72);
        //    PdfWriter.GetInstance(doc, new FileStream("myFile.pdf", FileMode.Create));
        //    doc.Open();

        //    // cycle through each page of the WPF FixedDocument
        //    DocumentPaginator paginator = fixedDocument.DocumentPaginator;
        //    for (int i = 0; i < paginator.PageCount; i++)
        //    {
        //        // render the fixed document to a WPF Visual object
        //        Visual visual = paginator.GetPage(i).Visual;

        //        // create a temporary file for the bitmap image
        //        string targetFile = Path.GetTempFileName();

        //        // convert XPS file to an image
        //        using (FileStream outStream = new FileStream(targetFile, FileMode.Create))
        //        {
        //            PngBitmapEncoder enc = new PngBitmapEncoder();
        //            enc.Frames.Add(BitmapFrame.Create(Bitmaps.CreateBitmapFromVisual(visual, 300, 300)));
        //            enc.Save(outStream);
        //        }

        //        // add the image to the iTextSharp PDF document
        //        using (FileStream fs = new FileStream(targetFile, FileMode.Open))
        //        {
        //            iTextSharp.text.Image png = iTextSharp.text.Image.GetInstance(System.Drawing.Image.FromStream(fs), System.Drawing.Imaging.ImageFormat.Png);
        //            png.ScalePercent(24f);
        //            doc.Add(png);
        //        }
        //    }
        //    doc.Close();




        //    //System.Windows.Window win = new System.Windows.Window();
        //    //win.Content = report;
        //    //win.Show();
            
            
        //}


        //private void DownloadPDF(string aspxPage, string fileName)
        //{
        //    string strHtml;
        //    //MemoryStream memStream = new MemoryStream();
        //    StringWriter strWriter = new StringWriter();

        //    Server.Execute(aspxPage, strWriter);
        //    strHtml = strWriter.ToString();

        //    strWriter.Close();
        //    strWriter.Dispose();
        //    string strFileShortName = fileName + DateTime.Now.Ticks + ".pdf";
        //    string strFileName = Server.MapPath("Acte\\" + strFileShortName);
        //    iTextSharp.text.Document docWorkingDocument = new iTextSharp.text.Document(iTextSharp.text.PageSize.A4, 72, 36, 36, 36);
        //    StringReader srdDocToString = null;
        //    try
        //    {
        //        PdfWriter pdfWriter;
        //        pdfWriter = PdfWriter.GetInstance(docWorkingDocument, new FileStream(strFileName, FileMode.Create));
        //        srdDocToString = new StringReader(strHtml);
        //        docWorkingDocument.Open();
        //        XMLWorkerHelper.GetInstance().ParseXHtml(pdfWriter, docWorkingDocument, srdDocToString);
        //    }
        //    catch (Exception ex)
        //    {
        //        Response.Write(ex.Message);
        //    }
        //    finally
        //    {
        //        if (docWorkingDocument != null)
        //        {
        //            docWorkingDocument.Close();
        //            docWorkingDocument.Dispose();
        //        }
        //        if (srdDocToString != null)
        //        {
        //            srdDocToString.Close();
        //            srdDocToString.Dispose();
        //        }
        //    }
        //    ///
        //    System.Web.HttpResponse res = System.Web.HttpContext.Current.Response;
        //    res.Clear();
        //    res.AppendHeader("content-disposition", "attachment; filename=" + strFileShortName);
        //    Response.ContentType = "application/pdf";
        //    res.WriteFile(strFileName);
        //    res.Flush();
        //    res.End();

        //}
        #endregion

        //private Link CreateInvoiceLink(InvoiceViewModel invoice)
        //{
        //    Link link = new Link();
        //    try
        //    {
        //        link.DisplayName = invoice.Number + " from " + invoice.Date.ToString("yyyy MM dd");
        //        Uri uri = new Uri(invoice.Id.ToString(), UriKind.Relative);
        //        link.Source = uri;
        //    }
        //    catch (Exception ex)
        //    {
        //        throw ex;
        //    }
        //    return link;
        //}

        private ICommand refreshCommand;

        public ICommand RefreshCommand
        {
            get
            {
                if (refreshCommand == null)
                {
                    refreshCommand = new Common.CommandBase(i => this.RefreshInvoices(), null);
                }
                return refreshCommand;
            }
        }

        private void RefreshInvoices()
        {
            //save client
            this.OnPropertyChanged("InvoiceLinks");
        }

        //private ICommand filterCommand;

        //public ICommand FilterCommand
        //{
        //    get
        //    {
        //        if (filterCommand == null)
        //        {
        //            filterCommand = new Common.CommandBase(i => this.FilterInvoices(), null);
        //        }
        //        return filterCommand;
        //    }
        //}

        //private void FilterInvoices()
        //{
        //    //save client
        //    this.OnPropertyChanged("InvoiceLinks");
        //}
    }

}
